home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
076-100
/
disk_096
/
animplayer
/
pack_frame.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
6KB
|
222 lines
/***************************************************************************
*
* NAME
* Pack_Frame -- store packed frame to disk
*
* SYNOPSIS
* if (!Pack_Frame( file, bitmapold, bitmapnew, colormap ))
*
* BPTR file;
* struct BitMap *bitmapold, *bitmapnew;
* UWORD *colormap;
*
* DESCRIPTION
* Packs an image that is part of an animation in RAM
* by saving the XOR of every other frame
* and exploiting frame coherence.
*
* copyright (c) 1987 Martin D. Hash
*
* LAST EDITED
* Martin Hash 22 Aug 1987
*
* EDIT HISTORY
* 25 Mar 1987 MH Created.
* 22 May Changed df1: to frames:
* 9 Jun Speeded up playback.
* 17 Jul Disk Full.
*
**********************************************************************/
#include <exec/types.h>
#include <intuition/intuition.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include "df1:FileCons.h"
#include "df1:ANIMCons.h"
/* EXTERNAL FUNCTIONS */
BOOL UserRequest();
/* LOCAL CONSTANTS */
#define Abort() goto Write_Error_Exit
/* FILE VARIABLES */
static int sizedummy1, sizedummy2;
static UWORD *dummy2,
*dummy1;
/* FUNCTION */
BOOL Pack_Frame( file, bitmapold, bitmapnew, colormap )
BPTR file;
struct BitMap *bitmapold, *bitmapnew;
UWORD *colormap;
{
/* LOCAL VARIABLES */
UWORD *offsetptr,
value,
*ptr1, *ptr2,
*position,
*dataptr;
int width,
plane,
i,
number,
maxrows,
column, row;
ULONG data[8],
offset[8],
firstpointer = POINTERBLOCK,
CMAPsize,
FORMsize,
DLTAsize;
BOOL done,
first;
ColorReg colorreg;
/* CODE */
sizedummy1 = bitmapnew->BytesPerRow/sizeof(UWORD)
*bitmapnew->Rows*sizeof(UWORD);
if ((dummy1 = (UWORD *)AllocMem( sizedummy1, 0 )) == NULL) {
UserRequest( " NOT ENOUGH MEMORY!" );
return FALSE;
}
sizedummy2 = bitmapold->BytesPerRow/sizeof(UWORD)
*bitmapold->Rows*sizeof(UWORD)*1.5;
if ((dummy2 = (UWORD *)AllocMem( sizedummy2, 0 )) == NULL) {
FreeMem( (UBYTE *)dummy1, sizedummy1 );
UserRequest( " NOT ENOUGH MEMORY!" );
return FALSE;
}
for (i = 0; i < 8; ++i) {
data[i] = 0;
offset[i] = 0;
}
width = bitmapold->BytesPerRow >>1;
maxrows = bitmapold->Rows;
dataptr = dummy1;
offsetptr = dummy2;
for (plane = 0; plane < bitmapold->Depth; ++plane) {
ptr1 = (UWORD *)bitmapold->Planes[plane];
ptr2 = (UWORD *)bitmapnew->Planes[plane];
done = FALSE;
column = 1;
row = 1;
while (TRUE) {
while ((*ptr1 ^ *ptr2) == 0) {
ptr1 += width;
ptr2 += width;
if (++row > maxrows) {
row = 1;
ptr1 = (UWORD *)bitmapold->Planes[plane] + column;
ptr2 = (UWORD *)bitmapnew->Planes[plane] + column;
if (++column > width) {
*offsetptr = 0xFFFF;
done = TRUE;
break;
}
}
}
if (done) {
++offsetptr;
break;
}
first = TRUE;
number = 0;
while ((value = *ptr1 ^ *ptr2) != 0) {
*dataptr++ = value;
if (first) {
first = FALSE;
position = ptr1;
}
ptr1 += width;
ptr2 += width;
++number;
if (++row > maxrows) {
row = 1;
ptr1 = (UWORD *)bitmapold->Planes[plane] + column;
ptr2 = (UWORD *)bitmapnew->Planes[plane] + column;
if (++column > width) {
done = TRUE;
*(offsetptr+2) = 0xFFFF;
}
break;
}
}
*offsetptr++ = position - (UWORD *)bitmapold->Planes[plane];
*offsetptr++ = number;
if (done) {
++offsetptr;
break;
}
}
data[plane] = POINTERBLOCK + dataptr - dummy1;
offset[plane] = offsetptr - dummy2;
}
if (Write( file, "FORM", 4*sizeof(char)) == -1)
Abort();
DLTAsize = (data[plane-1] + offset[plane-1]) * sizeof(UWORD);
FORMsize = (HEADERSIZE*sizeof(char) + HEADERSIZE*sizeof(char)
+ sizeof(ULONG) + sizeof(ColorReg)*COLORS
+ HEADERSIZE*sizeof(char) + sizeof(ULONG) + DLTAsize);
if (Write( file, &FORMsize, sizeof(ULONG)) == -1)
Abort();
if (Write( file, "ILBMCMAP", 8*sizeof(char)) == -1)
Abort();
CMAPsize = sizeof(ColorReg)*COLORS;
if (Write( file, &CMAPsize, sizeof(ULONG)) == -1)
Abort();
for (i = 0; i < COLORS; ++i) {
colorreg.red = (*colormap>>4) & 0xF0;
colorreg.green = *colormap & 0xF0;
colorreg.blue = (*colormap<<4) & 0xF0;
if (Write( file, (UBYTE *)&colorreg, sizeof(ColorReg)) == -1)
Abort();
++colormap;
}
if (Write( file, "DLTA", 4*sizeof(char)) == -1)
Abort();
if (Write( file, &DLTAsize, sizeof(ULONG)) == -1)
Abort();
for (i = 0; i < plane; ++i)
offset[i] += data[plane-1];
if (Write( file, &firstpointer, sizeof(ULONG)) == -1)
Abort();
if (Write( file, &data[0], 7*sizeof(ULONG)) == -1)
Abort();
if (Write( file, &data[plane-1], sizeof(ULONG)) == -1)
Abort();
if (Write( file, &offset[0], 7*sizeof(ULONG)) == -1)
Abort();
if (Write( file, dummy1, (data[plane-1]-POINTERBLOCK)*sizeof(UWORD))== -1)
Abort();
if (Write( file, dummy2, (offset[plane-1]-data[plane-1])*sizeof(UWORD))
== -1)
Abort();
FreeMem((UBYTE *)dummy1, sizedummy1 );
FreeMem((UBYTE *)dummy2, sizedummy2 );
return TRUE;
Write_Error_Exit:
FreeMem((UBYTE *)dummy1, sizedummy1 );
FreeMem((UBYTE *)dummy2, sizedummy2 );
return FALSE;
}